package com.tanhua.sso.service;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.mapper.AdminMapper;
import com.tanhua.common.pojo.Admin;
import com.tanhua.common.vo.AdminVo;
import com.tanhua.common.vo.ErrorResult;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class SystemService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private AdminMapper adminMapper;

    @Value("${jwt.secret}")
    private String secret;      //盐值

    @Autowired
    private UserService userService;

    //private String randString = "0123456789";//随机产生只有数字的字符串 private String
    //private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生只有字母的字符串
    private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生数字与字母组合的字符串
    private int width = 95;// 图片宽
    private int height = 25;// 图片高
    private int lineSize = 40;// 干扰线数量
    private int stringNum = 4;// 随机产生字符数量
    private Random random = new Random();


    //登录校验 返回token
    public Map<String, Object> queryToken(AdminVo adminVo) {
        String redisKey = "CHECK_CODE_" + adminVo.getUuid();
        //1.获取redis中的验证码
        String redisCode = redisTemplate.opsForValue().get(redisKey);
        //2.与前台验证码进行比较验证
        if (!adminVo.getVerificationCode().equalsIgnoreCase(redisCode)) {
            //比较失败 返回客户结果
            throw new BusinessException(ErrorResult.checkCodeError());
        }
        //通过验证码,在判断用户名密码是否正确


        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.eq("username",adminVo.getUsername()).eq("password",adminVo.getPassword());
        Admin oneAdmin = this.adminMapper.selectOne(wrapper);
        if (ObjectUtil.isEmpty(oneAdmin)){
            throw new BusinessException(ErrorResult.tokenError());
        }
        //校验完成, 清除rediskey的验证码
        redisTemplate.delete(redisKey);

        //token的头部信息
        Map<String, Object> header = new HashMap<String, Object>();
        header.put(JwsHeader.TYPE, JwsHeader.JWT_TYPE);
        header.put(JwsHeader.ALGORITHM, "HS256");


        //令牌中payload的信息
        Map<String, Object> claims = new HashMap<>();
        claims.put("uid",oneAdmin.getUid());
        claims.put("username", adminVo.getUsername());

        //生成token
        String token = Jwts.builder()
                .setHeader(header)          //可省略
                .setClaims(claims)          //payload 存放数据
                .signWith(SignatureAlgorithm.HS256, secret)   //加密算法 加盐
                .setExpiration(new DateTime().plusDays(20).toDate())   //设置过期时间
                .compact();



        //保存响应数据
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);  //token
        return map;
    }


    //用户信息
    public Admin profile(String token) {
        token = token.split(" ")[1];
        Admin admin = this.getToken(token);

        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.eq("uid",admin.getUid());
        Admin result = this.adminMapper.selectOne(wrapper);
        return result;
    }

    //退出
    public void delToken(String token) {
        if (!redisTemplate.hasKey(token)){
            return;
        }
        redisTemplate.delete(token);
    }


    //解析
    public Admin getToken(String token) {
        try {
            //解析token,获取body内容
            Map<String , Object> body = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
            //将body中的内容封装到user对象中
            ObjectMapper objectMapper = new ObjectMapper();    //json对象
            String json = objectMapper.writeValueAsString(body);  //json序列化对象
            Admin ad = JSON.parseObject(json, Admin.class);     //解析json成user对象
            QueryWrapper<Admin> wrapper = new QueryWrapper<>();
            wrapper.eq("uid",ad.getUid());
            Admin admin = this.adminMapper.selectOne(wrapper);
            return admin;
        } catch (Exception e) {
            throw new BusinessException(ErrorResult.tokenError());
        }
    }
}
